package cn.zhfeat.utils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * @Title ObjectUtils.java
 * @Description 对象和map互转方法
 * @author wschenyongyin
 * @date 2018年3月6日
 * @version 1.0
 */
public class ObjectUtils {

	private static final String JAVAP = "java.";
	private static final String JAVADATESTR = "java.util.Date";

	/**
	 * 
	 * @Function: ObjectUtils.java
	 * @Description: 对象转map
	 *
	 * @param:
	 * @return：Map<String, Object>
	 * @throws：IllegalAccessException
	 *
	 * @author: wsche
	 * @date: 2018年3月6日 下午3:10:52
	 */
	public static Map<String, Object> objectToMap(Object obj, String... excludeFields) throws IllegalAccessException {
		Map<String, Object> map = new HashMap<String, Object>();
		Class<?> clazz = obj.getClass();
		System.out.println(clazz);
		for (Field field : clazz.getDeclaredFields()) {
			field.setAccessible(true);
			String fieldName = field.getName();
			Object value = field.get(obj);
			if (excludeFields != null && excludeFields.length > 0) {
				if (!hasFieId(fieldName, excludeFields)) {
					map.put(fieldName, value);
				}
			} else {
				map.put(fieldName, value);
			}
		}
		return map;
	}

	/**
	 * 
	 * @Description:
	 * @param obj
	 * @param excludeFields
	 * @return
	 * @throws IllegalAccessException
	 *
	 * @author: wschenyongyin
	 * @date: 2018年3月9日 上午10:16:21
	 */
	public static Map<String, String> objectToMapStr(Object obj, String... excludeFields)
			throws IllegalAccessException {
		Map<String, String> map = new HashMap<String, String>();
		Class<?> clazz = obj.getClass();
		for (Field field : clazz.getDeclaredFields()) {
			field.setAccessible(true);
			String fieldName = field.getName();
			String value = String.valueOf(field.get(obj));
			if (excludeFields != null && excludeFields.length > 0) {
				if (!hasFieId(fieldName, excludeFields)) {
					map.put(fieldName, value);
				}
			} else {
				map.put(fieldName, value);
			}
		}
		return map;
	}

	private static Boolean hasFieId(String fieId, String[] fieIds) {
		boolean result = false;
		for (String excludeFieId : fieIds) {
			if (fieId.equals(excludeFieId)) {
				result = true;
				break;
			}
		}
		return result;
	}

	/**
	 * 
	 * @Function: ObjectUtils.java
	 * @Description: Map<Stirng,Object> 转pojo
	 *
	 * @param: @return：
	 * @throws：
	 *
	 * @author: wschenyongyin
	 * @date: 2018年3月6日 下午3:19:24
	 */
	public static Object objMapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
		if (map == null)
			return null;

		Object obj = beanClass.newInstance();

		Field[] fields = obj.getClass().getDeclaredFields();
		for (Field field : fields) {
			int mod = field.getModifiers();
			if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
				continue;
			}

			field.setAccessible(true);
			field.set(obj, map.get(field.getName()));
		}

		return obj;
	}

	/**
	 * 
	 * @Function: ObjectUtils.java
	 * @Description: Map<String,String> 转 POJO
	 *
	 * @param: @return：
	 * @throws：
	 *
	 * @author: wschenyongyin
	 * @date: 2018年3月6日 下午3:19:57
	 */
	public static Object strMapToObject(Map<String, String> map, Class<?> beanClass) throws Exception {
		if (map == null)
			return null;
		Object obj = beanClass.newInstance();

		Field[] fields = obj.getClass().getDeclaredFields();
		for (Field field : fields) {
			int mod = field.getModifiers();
			if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
				continue;
			}

			field.setAccessible(true);
			field.set(obj, map.get(field.getName()));
		}
		return obj;
	}

	/**
	 * 
	* @Description: 将一个类转换成另一个类
	* @param oneObj
	* @param anotherClassObj
	* @return
	*
	* @author: wschenyongyin
	* @date: 2018年3月9日 下午5:05:01
	 */
	public static <K, V> V toAnotherObj(K oneObj, Class<V> anotherClassObj,String... excludeFields) {
		V anotherObj = null;
		try {
			anotherObj = anotherClassObj.newInstance();
			Class<?> oneClassObj = oneObj.getClass();
			Field[] fields = getMatchedFields(oneClassObj,excludeFields);
			for (Field field : fields) {
				String fieldName = field.getName();
				String append = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
				String getMethodName = "get" + append;
				String setMethodName = "set" + append;
				Method getMethod = oneClassObj.getDeclaredMethod(getMethodName);
				getMethod.setAccessible(true);
				Object attrForOneObj = getMethod.invoke(oneObj);
				Method setMethod = anotherClassObj.getDeclaredMethod(setMethodName, field.getType());
				setMethod.setAccessible(true);
				setMethod.invoke(anotherObj, attrForOneObj);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return anotherObj;
	}

	private static Field[] getMatchedFields(Class<?> classObj,String... excludeFields) {
		List<Field> matchedFields = new ArrayList<Field>();
		Field[] fields = classObj.getDeclaredFields();
		for (Field field : fields) {
			if(!hasFieId(field.getName(), excludeFields)) {
				System.out.println(field.getName());
				matchedFields.add(field);
			}
		}

		return matchedFields.toArray(new Field[] {});
	}
}
